package repository

import (
	"shyxy-model-agent/common/cache/lru"
	"shyxy-model-agent/core/model"

	"gorm.io/gorm"
)

type modelInfoRepository struct {
	*BaseRepository
}

func NewModelInfoRepository(db *gorm.DB) ModelInfoRepository {
	return &modelInfoRepository{
		BaseRepository: NewBaseRepository(db),
	}
}
func (mir *modelInfoRepository) Create(modelInfo *model.ModelInfo) (uint, error) {
	err := mir.GetDB().Create(modelInfo).Error
	if err != nil {
		return 0, err
	}
	return modelInfo.ID, nil
}

func (mir *modelInfoRepository) FindOneByName(name string) (*model.ModelInfo, error) {
	var modelInfo model.ModelInfo
	err := mir.GetDB().Where("name = ?", name).First(&modelInfo).Error
	return &modelInfo, err
}

func (mir *modelInfoRepository) FindOneByID(id uint) (*model.ModelInfo, error) {
	var modelInfo model.ModelInfo
	err := mir.GetDB().Where("id = ?", id).First(&modelInfo).Error
	return &modelInfo, err
}

func (mir *modelInfoRepository) FindListByCategory(category string) ([]*model.ModelInfo, error) {
	var modelInfos []*model.ModelInfo
	err := mir.GetDB().Where("category = ?", category).Find(&modelInfos).Error
	return modelInfos, err
}

func (mir *modelInfoRepository) UpdateStatusByID(id uint, status string) error {
	return mir.GetDB().Model(&model.ModelInfo{}).Where("id = ?", id).Update("status", status).Error
}

func (mir *modelInfoRepository) FindListByStatusAndName(name string, status ...string) ([]*model.ModelInfo, error) {
	var modelInfos []*model.ModelInfo
	err := mir.GetDB().Where("name LIKE ?", "%"+name+"%").Where("status IN (?)", status).Find(&modelInfos).Error
	return modelInfos, err
}

func (mir *modelInfoRepository) FindListAll() ([]*model.ModelInfo, error) {
	var modelInfos []*model.ModelInfo
	err := mir.GetDB().Find(&modelInfos).Error
	return modelInfos, err
}

func (mir *modelInfoRepository) DeleteByID(id uint) error {
	return mir.GetDB().Where("id = ?", id).Delete(&model.ModelInfo{}).Error
}

type cachedModelInfoRepository struct {
	*BaseCachedRepository
}

func (cmir *cachedModelInfoRepository) CachedRepository() {}

func NewCachedModelInfoRepository(db *gorm.DB, cache *lru.LRU) ModelInfoRepository {
	return &cachedModelInfoRepository{NewBaseCachedRepository(db, cache, "model_info")}
}

func (cmir *cachedModelInfoRepository) Create(modelInfo *model.ModelInfo) (uint, error) {
	id, err := (&modelInfoRepository{BaseRepository: NewBaseRepository(cmir.GetDB())}).Create(modelInfo)
	if err == nil && cmir.GetCache() != nil {
		// 清除相关缓存
		cmir.GetCache().Remove(cmir.GenerateCacheKey("name", modelInfo.Name))
		cmir.GetCache().Remove(cmir.GenerateCacheKey("list_all"))
		return id, nil
	}
	return 0, err
}

func (cmir *cachedModelInfoRepository) FindOneByName(name string) (*model.ModelInfo, error) {
	if cmir.GetCache() == nil {
		// 如果没有缓存，直接使用基础实现
		return (&modelInfoRepository{BaseRepository: NewBaseRepository(cmir.GetDB())}).FindOneByName(name)
	}

	cacheKey := cmir.GenerateCacheKey("name", name)

	// 先查缓存
	if cached, ok := cmir.GetCache().Get(cacheKey); ok {
		if modelInfo, ok := cached.(*model.ModelInfo); ok {
			return modelInfo, nil
		}
	}

	// 缓存未命中，查询数据库
	modelInfo, err := (&modelInfoRepository{BaseRepository: NewBaseRepository(cmir.GetDB())}).FindOneByName(name)
	if err == nil {
		// 查询成功，加入缓存
		cmir.GetCache().Add(cacheKey, modelInfo)
	}
	return modelInfo, err
}
func (cmir *cachedModelInfoRepository) FindOneByID(id uint) (*model.ModelInfo, error) {
	if cmir.GetCache() == nil {
		// 如果没有缓存，直接使用基础实现
		return (&modelInfoRepository{BaseRepository: NewBaseRepository(cmir.GetDB())}).FindOneByID(id)
	}

	cacheKey := cmir.GenerateCacheKey("id", id)

	// 先查缓存
	if cached, ok := cmir.GetCache().Get(cacheKey); ok {
		if modelInfo, ok := cached.(*model.ModelInfo); ok {
			return modelInfo, nil
		}
	}

	// 缓存未命中，查询数据库
	modelInfo, err := (&modelInfoRepository{BaseRepository: NewBaseRepository(cmir.GetDB())}).FindOneByID(id)
	if err == nil {
		// 查询成功，加入缓存
		cmir.GetCache().Add(cacheKey, modelInfo)
		// 同时用 name 作为键缓存
		cmir.GetCache().Add(cmir.GenerateCacheKey("name", modelInfo.Name), modelInfo)
	}
	return modelInfo, err
}

func (cmir *cachedModelInfoRepository) FindListByCategory(category string) ([]*model.ModelInfo, error) {
	// 列表查询通常不缓存，直接查询数据库
	return (&modelInfoRepository{BaseRepository: NewBaseRepository(cmir.GetDB())}).FindListByCategory(category)
}

func (cmir *cachedModelInfoRepository) UpdateStatusByID(id uint, status string) error {
	// 先查询原数据，用于清理缓存
	oldModelInfo, _ := cmir.FindOneByID(id)

	// 更新数据库
	err := (&modelInfoRepository{BaseRepository: NewBaseRepository(cmir.GetDB())}).UpdateStatusByID(id, status)

	if err == nil && oldModelInfo != nil && cmir.GetCache() != nil {
		// 清理相关缓存
		cmir.GetCache().Remove(cmir.GenerateCacheKey("id", id))
		cmir.GetCache().Remove(cmir.GenerateCacheKey("name", oldModelInfo.Name))
		cmir.GetCache().Remove(cmir.GenerateCacheKey("list_all"))
	}

	return err
}

func (cmir *cachedModelInfoRepository) FindListByStatusAndName(name string, status ...string) ([]*model.ModelInfo, error) {
	// 带参数的列表查询通常不缓存，直接查询数据库
	return (&modelInfoRepository{BaseRepository: NewBaseRepository(cmir.GetDB())}).FindListByStatusAndName(name, status...)
}

func (cmir *cachedModelInfoRepository) FindListAll() ([]*model.ModelInfo, error) {
	if cmir.GetCache() == nil {
		// 如果没有缓存，直接使用基础实现
		return (&modelInfoRepository{BaseRepository: NewBaseRepository(cmir.GetDB())}).FindListAll()
	}

	cacheKey := cmir.GenerateCacheKey("list_all")

	// 先查缓存
	if cached, ok := cmir.GetCache().Get(cacheKey); ok {
		if modelInfos, ok := cached.([]*model.ModelInfo); ok {
			return modelInfos, nil
		}
	}

	// 缓存未命中，查询数据库
	modelInfos, err := (&modelInfoRepository{BaseRepository: NewBaseRepository(cmir.GetDB())}).FindListAll()
	if err == nil {
		// 查询成功，加入缓存
		cmir.GetCache().Add(cacheKey, modelInfos)
	}
	return modelInfos, err
}

func (cmir *cachedModelInfoRepository) DeleteByID(id uint) error {
	// 先查询原数据，用于清理缓存
	oldModelInfo, _ := cmir.FindOneByID(id)

	// 删除数据库记录
	err := (&modelInfoRepository{BaseRepository: NewBaseRepository(cmir.GetDB())}).DeleteByID(id)

	if err == nil && oldModelInfo != nil && cmir.GetCache() != nil {
		// 清理相关缓存
		cmir.GetCache().Remove(cmir.GenerateCacheKey("id", id))
		cmir.GetCache().Remove(cmir.GenerateCacheKey("name", oldModelInfo.Name))
		cmir.GetCache().Remove(cmir.GenerateCacheKey("list_all"))
	}

	return err
}

func NewModelInfoRepositoryWithCache(db *gorm.DB, cache *lru.LRU) ModelInfoRepository {
	if cache != nil {
		return NewCachedModelInfoRepository(db, cache)
	}
	return NewModelInfoRepository(db)
}
